home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJINC106.ARJ / BITSTRIN.H < prev    next >
C/C++ Source or Header  |  1992-03-29  |  20KB  |  765 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #ifndef _BitString_h
  20. #ifdef __GNUG__
  21. #pragma interface
  22. #endif
  23.  
  24. #define _BitString_h 1
  25.  
  26. #include <stream.h>
  27. #include <values.h>
  28.  
  29. #define BITSTRBITS   BITS(short)
  30.  
  31. struct BitStrRep
  32. {
  33.   unsigned int    len;          // length in bits
  34.   unsigned short  sz;           // allocated slots
  35.   unsigned short  s[1];         // bits start here
  36. };
  37.  
  38. extern BitStrRep*  BStr_alloc(BitStrRep*, const unsigned short*, int, int,int);
  39. extern BitStrRep*  BStr_resize(BitStrRep*, int);
  40. extern BitStrRep*  BStr_copy(BitStrRep*, const BitStrRep*);
  41. extern BitStrRep*  cmpl(const BitStrRep*, BitStrRep*);
  42. extern BitStrRep*  and(const BitStrRep*, const BitStrRep*, BitStrRep*);
  43. extern BitStrRep*  or(const BitStrRep*, const BitStrRep*, BitStrRep*);
  44. extern BitStrRep*  xor(const BitStrRep*, const BitStrRep*, BitStrRep*);
  45. extern BitStrRep*  diff(const BitStrRep*, const BitStrRep*, BitStrRep*);
  46. extern BitStrRep*  cat(const BitStrRep*, const BitStrRep*, BitStrRep*);
  47. extern BitStrRep*  cat(const BitStrRep*, unsigned int, BitStrRep*);
  48. extern BitStrRep*  lshift(const BitStrRep*, int, BitStrRep*);
  49.  
  50.  
  51. class BitString;
  52. class BitPattern;
  53.  
  54. class BitStrBit
  55. {
  56. protected:
  57.   BitString&        src;
  58.   unsigned int      pos;
  59.  
  60.  public:
  61.                     BitStrBit(BitString& v, int p);
  62.                     BitStrBit(const BitStrBit& b);
  63.                    ~BitStrBit();
  64.                     operator unsigned int() const;
  65.   int               operator =  (unsigned int b);
  66.   int               operator == (unsigned int b) const ;
  67.   int               operator != (unsigned int b) const ;
  68. };
  69.  
  70. class BitSubString
  71. {
  72.   friend class      BitString;
  73.   friend class      BitPattern;
  74.  
  75. protected:
  76.  
  77.   BitString&        S;
  78.   unsigned int      pos;
  79.   unsigned int      len;
  80.  
  81.                     BitSubString(BitString& x, int p, int l);
  82.                     BitSubString(const BitSubString& x);
  83. public:
  84.                     ~BitSubString();
  85.  
  86.   void              operator =  (const BitString&);
  87.   void              operator =  (const BitSubString&);
  88.  
  89.   int               length() const;
  90.   int               empty() const;
  91.  
  92.   int               OK() const;
  93. };
  94.  
  95. class BitString
  96. {
  97.   friend class       BitSubString;
  98.   friend class       BitPattern;
  99. protected:
  100.   BitStrRep*         rep;
  101.  
  102.   int                search(int, int, const unsigned short*, int, int) const;
  103.   int                match(int, int, int, const unsigned short*,int,int) const;
  104.   BitSubString       _substr(int first, int l);
  105.  
  106. public:
  107.  
  108. // constructors
  109.                      BitString();
  110.                      BitString(const BitString&);
  111.                      BitString(const BitSubString& y);
  112.  
  113.                     ~BitString();
  114.  
  115.   void               operator =  (unsigned int bit);
  116.   void               operator =  (const BitString& y);
  117.   void               operator =  (const BitSubString& y);
  118.  
  119. // equality & subset tests
  120.  
  121.   friend int         operator == (const BitString&, const BitString&);
  122.   friend int         operator != (const BitString&, const BitString&);
  123.   friend int         operator <  (const BitString&, const BitString&);
  124.   friend int         operator <= (const BitString&, const BitString&);
  125.   friend int         operator >  (const BitString&, const BitString&);
  126.   friend int         operator >= (const BitString&, const BitString&);
  127.  
  128. // procedural versions of operators
  129.  
  130.  
  131.   friend void        and(const BitString&, const BitString&, BitString&);
  132.   friend void        or(const BitString&, const BitString&, BitString&);
  133.   friend void        xor(const BitString&, const BitString&, BitString&);
  134.   friend void        diff(const BitString&, const BitString&, BitString&);
  135.   friend void        cat(const BitString&, const BitString&, BitString&);
  136.   friend void        cat(const BitString&, unsigned int, BitString&);
  137.   friend void        lshift(const BitString&, int, BitString&);
  138.   friend void        rshift(const BitString&, int, BitString&);
  139.  
  140.   friend void        complement(const BitString&, BitString&);
  141.  
  142.   friend int         lcompare(const BitString&, const BitString&); 
  143.  
  144. // assignment-based operators
  145. // (constuctive versions decalred inline below
  146.  
  147.   void               operator |= (const BitString&);
  148.   void               operator &= (const BitString&);
  149.   void               operator -= (const BitString&);
  150.   void               operator ^= (const BitString&);
  151.   void               operator += (const BitString&);
  152.   void               operator += (unsigned int b);
  153.   void               operator <<=(int s);
  154.   void               operator >>=(int s);
  155.  
  156.   void               complement();
  157.  
  158. // individual bit manipulation
  159.  
  160.   void               set(int pos);
  161.   void               set(int from, int to);
  162.   void               set();
  163.  
  164.   void               clear(int pos);
  165.   void               clear(int from, int to);
  166.   void               clear(); 
  167.  
  168.   void               invert(int pos);
  169.   void               invert(int from, int to);
  170.  
  171.   int                test(int pos) const;
  172.   int                test(int from, int to) const;
  173.  
  174.   void               assign(int p, unsigned int bit);
  175.  
  176. // indexing
  177.  
  178.   BitStrBit          operator [] (int pos);
  179.  
  180. // iterators
  181.  
  182.   int                first(unsigned int bit = 1) const;
  183.   int                last(unsigned int b = 1) const;
  184.  
  185.   int                next(int pos, unsigned int b = 1) const;
  186.   int                previous(int pos, unsigned int b = 1) const;
  187.  
  188. // searching & matching
  189.  
  190.   int                index(unsigned int bit, int startpos = 0) const ;      
  191.   int                index(const BitString&, int startpos = 0) const;
  192.   int                index(const BitSubString&, int startpos = 0) const;
  193.   int                index(const BitPattern&, int startpos = 0) const;
  194.  
  195.   int                contains(const BitString&) const;
  196.   int                contains(const BitSubString&) const;
  197.   int                contains(const BitPattern&) const;
  198.  
  199.   int                contains(const BitString&, int pos) const;
  200.   int                contains(const BitSubString&, int pos) const;
  201.   int                contains(const BitPattern&, int pos) const;
  202.  
  203.   int                matches(const BitString&, int pos = 0) const;
  204.   int                matches(const BitSubString&, int pos = 0) const;
  205.   int                matches(const BitPattern&, int pos = 0) const;
  206.  
  207. // BitSubString extraction
  208.  
  209.   BitSubString       at(int pos, int len);
  210.   BitSubString       at(const BitString&, int startpos = 0); 
  211.   BitSubString       at(const BitSubString&, int startpos = 0); 
  212.   BitSubString       at(const BitPattern&, int startpos = 0); 
  213.  
  214.   BitSubString       before(int pos);
  215.   BitSubString       before(const BitString&, int startpos = 0);
  216.   BitSubString       before(const BitSubString&, int startpos = 0);
  217.   BitSubString       before(const BitPattern&, int startpos = 0);
  218.  
  219.   BitSubString       after(int pos);
  220.   BitSubString       after(const BitString&, int startpos = 0);
  221.   BitSubString       after(const BitSubString&, int startpos = 0);
  222.   BitSubString       after(const BitPattern&, int startpos = 0);
  223.  
  224. // other friends & utilities
  225.  
  226.   friend BitString   common_prefix(const BitString&, const BitString&, 
  227.                                    int pos = 0);
  228.   friend BitString   common_suffix(const BitString&, const BitString&, 
  229.                                    int pos = -1);
  230.   friend BitString   reverse(const BitString&);
  231.  
  232.   void               right_trim(unsigned int bit);
  233.   void               left_trim(unsigned int bit);
  234.  
  235. // status
  236.  
  237.   int                empty() const ;
  238.   int                count(unsigned int bit = 1) const;
  239.   int                length() const;
  240.  
  241. // convertors & IO
  242.  
  243.   friend BitString   atoBitString(const char* s, char f='0', char t='1');
  244.   friend const char* BitStringtoa(const BitString&, char f='0', char t='1');
  245.  
  246.   friend BitString   shorttoBitString(unsigned short);
  247.   friend BitString   longtoBitString(unsigned long);
  248.  
  249.   friend ostream&    operator << (ostream& s, const BitString&);
  250.  
  251. // misc
  252.  
  253.   void      error(const char* msg) const;
  254.  
  255. // indirect friends
  256.  
  257.   friend const char* BitPatterntoa(const BitPattern& p, 
  258.                                   char f='0',char t='1',char x='X');
  259.   friend BitPattern  atoBitPattern(const char* s,
  260.                                   char f='0',char t='1',char x='X');
  261.  
  262.   int                OK() const;
  263. };
  264.  
  265.  
  266. class BitPattern
  267. {
  268. public:
  269.   BitString          pattern;
  270.   BitString          mask;
  271.  
  272.                      BitPattern();
  273.                      BitPattern(const BitPattern&);
  274.                      BitPattern(const BitString& p, const BitString& m);
  275.  
  276.                     ~BitPattern();
  277.  
  278.   friend const char* BitPatterntoa(const BitPattern&, char f, char t, char x);
  279.   friend BitPattern atoBitPattern(const char* s, char f,char t, char x);
  280.   friend ostream&   operator << (ostream& s, const BitPattern&);
  281.  
  282.   int               search(const unsigned short*, int, int) const;
  283.   int               match(const unsigned short* xs, int, int, int) const;
  284.  
  285.   int               OK() const;
  286. };
  287.  
  288. BitString  operator & (const BitString& x, const BitString& y);
  289. BitString  operator | (const BitString& x, const BitString& y);
  290. BitString  operator ^ (const BitString& x, const BitString& y);
  291. BitString  operator << (const BitString& x, int y);
  292. BitString  operator >> (const BitString& x, int y);
  293. BitString  operator - (const BitString& x, const BitString& y);
  294. BitString  operator + (const BitString& x, const BitString& y);
  295. BitString  operator + (const BitString& x, unsigned int y);
  296. BitString  operator ~ (const BitString& x);
  297. int operator != (const BitString& x, const BitString& y);
  298. int operator>(const BitString& x, const BitString& y);
  299. int operator>=(const BitString& x, const BitString& y);
  300.  
  301. extern BitStrRep    _nilBitStrRep;
  302. extern BitString    _nil_BitString;
  303.  
  304. // primitive bit extraction
  305.  
  306. // These must be inlined regardless of optimization.
  307.  
  308. inline int BitStr_index(int l) { return (unsigned)(l) / BITSTRBITS; }
  309.  
  310. inline int BitStr_pos(int l) { return l & (BITSTRBITS - 1); }
  311.  
  312.  
  313. // constructors & assignment
  314.  
  315. inline BitString::BitString() :rep(&_nilBitStrRep) {}
  316.  
  317. inline BitString::BitString(const BitString& x) :rep(BStr_copy(0, x.rep)) {}
  318.  
  319. inline BitString::BitString(const BitSubString& y) 
  320.    :rep (BStr_alloc(0, y.S.rep->s, y.pos, y.pos+y.len, y.len)) {}
  321.  
  322. inline BitString::~BitString()
  323.   if (rep != &_nilBitStrRep) delete rep;
  324. }
  325.  
  326. #if defined(__GNUG__) && !defined(NO_NRV)
  327.  
  328. inline BitString shorttoBitString(unsigned short w) return r
  329.   r.rep = BStr_alloc(0, &w, 0, BITSTRBITS, BITSTRBITS);
  330. }
  331.  
  332. inline BitString longtoBitString(unsigned long w) return r
  333.   unsigned short u[2];
  334.   u[0] = w & ((unsigned short)(~(0)));
  335.   u[1] = w >> BITSTRBITS;
  336.   r.rep = BStr_alloc(0, &u[0], 0, 2*BITSTRBITS, 2*BITSTRBITS);
  337. }
  338.  
  339. #else
  340.  
  341. inline BitString shorttoBitString(unsigned short w) 
  342.   BitString r; r.rep = BStr_alloc(0, &w, 0, BITSTRBITS, BITSTRBITS); return r;
  343. }
  344.  
  345. inline BitString longtoBitString(unsigned long w) 
  346.   BitString r;
  347.   unsigned short u[2];
  348.   u[0] = w & ((unsigned short)(~(0)));
  349.   u[1] = w >> BITSTRBITS;
  350.   r.rep = BStr_alloc(0, &u[0], 0, 2*BITSTRBITS, 2*BITSTRBITS);
  351.   return r;
  352. }
  353.  
  354. #endif
  355.  
  356. inline void BitString::operator =  (const BitString& y)
  357.   rep = BStr_copy(rep, y.rep);
  358. }
  359.  
  360. inline void BitString::operator = (unsigned int b)
  361.   unsigned short bit = b;
  362.   rep = BStr_alloc(rep, &bit, 0, 1, 1);
  363. }
  364.  
  365. inline void BitString::operator=(const BitSubString&  y)
  366. {
  367.   rep = BStr_alloc(rep, y.S.rep->s, y.pos, y.pos+y.len, y.len);
  368. }
  369.  
  370. inline BitSubString::BitSubString(const BitSubString& x) 
  371.     :S(x.S), pos(x.pos), len(x.len) {}
  372.  
  373. inline BitSubString::BitSubString(BitString& x, int p, int l)
  374.      : S(x), pos(p), len(l) {}
  375.  
  376. inline BitSubString::~BitSubString() {}
  377.  
  378. inline BitPattern::BitPattern(const BitString& p, const BitString& m)
  379.     :pattern(p), mask(m) {}
  380.  
  381. inline BitPattern::BitPattern(const BitPattern& b)
  382.     :pattern(b.pattern), mask(b.mask) {}
  383.  
  384. inline BitPattern::BitPattern() {}
  385. inline BitPattern::~BitPattern() {}
  386.  
  387.  
  388. // procedural versions of operators
  389.  
  390. inline void and(const BitString& x, const BitString& y, BitString& r)
  391. {
  392.   r.rep = and(x.rep, y.rep, r.rep);
  393. }
  394.  
  395. inline void or(const BitString& x, const BitString& y, BitString& r)
  396. {
  397.   r.rep = or(x.rep, y.rep, r.rep);
  398. }
  399.  
  400. inline void xor(const BitString& x, const BitString& y, BitString& r)
  401. {
  402.   r.rep = xor(x.rep, y.rep, r.rep);
  403. }
  404.  
  405. inline void diff(const BitString& x, const BitString& y, BitString& r)
  406. {
  407.   r.rep = diff(x.rep, y.rep, r.rep);
  408. }
  409.  
  410. inline void cat(const BitString& x, const BitString& y, BitString& r)
  411. {
  412.   r.rep = cat(x.rep, y.rep, r.rep);
  413. }
  414.  
  415. inline void cat(const BitString& x, unsigned int y, BitString& r)
  416. {
  417.   r.rep = cat(x.rep, y, r.rep);
  418. }
  419.  
  420. inline void rshift(const BitString& x, int y, BitString& r)
  421. {
  422.   r.rep = lshift(x.rep, -y, r.rep);
  423. }
  424.  
  425. inline void lshift(const BitString& x, int y, BitString& r)
  426. {
  427.   r.rep = lshift(x.rep, y, r.rep);
  428. }
  429.  
  430. inline void complement(const BitString& x, BitString& r)
  431. {
  432.   r.rep = cmpl(x.rep, r.rep);
  433. }
  434.  
  435. // operators
  436.  
  437.  
  438. inline void BitString::operator &= (const BitString& y)
  439. {
  440.   and(*this, y, *this);
  441. }
  442.  
  443.  
  444. inline void BitString::operator |= (const BitString& y)
  445. {
  446.   or(*this, y, *this);
  447. }
  448.  
  449. inline void BitString::operator ^= (const BitString& y)
  450. {
  451.   xor(*this, y, *this);
  452. }
  453.  
  454. inline void BitString::operator <<= (int y)
  455. {
  456.   lshift(*this, y, *this);
  457. }
  458.  
  459. inline void BitString::operator >>= (int y)
  460. {
  461.   rshift(*this, y, *this);
  462. }
  463.  
  464. inline void BitString::operator -= (const BitString& y)
  465. {
  466.   diff(*this, y, *this);
  467. }
  468.  
  469. inline void BitString::operator += (const BitString& y)
  470. {
  471.   cat(*this, y, *this);
  472. }
  473.  
  474. inline void BitString::operator += (unsigned int y)
  475. {
  476.   cat(*this, y, *this);
  477. }
  478.  
  479. inline void BitString::complement()
  480. {
  481.   ::complement(*this, *this);
  482. }
  483.  
  484. #if defined(__GNUG__) && !defined(NO_NRV)
  485.  
  486. inline BitString  operator & (const BitString& x, const BitString& y) return r
  487. {
  488.   and(x, y, r);
  489. }
  490.  
  491. inline BitString  operator | (const BitString& x, const BitString& y) return r
  492. {
  493.   or(x, y, r);
  494. }
  495.  
  496. inline BitString  operator ^ (const BitString& x, const BitString& y) return r
  497. {
  498.   xor(x, y, r);
  499. }
  500.  
  501. inline BitString  operator << (const BitString& x, int y) return r
  502. {
  503.   lshift(x, y, r);
  504. }
  505.  
  506. inline BitString  operator >> (const BitString& x, int y) return r
  507. {
  508.   rshift(x, y, r);
  509. }
  510.  
  511. inline BitString  operator - (const BitString& x, const BitString& y) return r
  512. {
  513.   diff(x, y, r);
  514. }
  515.  
  516. inline BitString  operator + (const BitString& x, const BitString& y) return r
  517. {
  518.   cat(x, y, r);
  519. }
  520.  
  521. inline BitString  operator + (const BitString& x, unsigned int y) return r
  522. {
  523.   cat(x, y, r);
  524. }
  525.  
  526. inline BitString  operator ~ (const BitString& x) return r
  527. {
  528.   complement(x, r);
  529. }
  530.  
  531. #else /* NO_NRV */
  532.  
  533. inline BitString  operator & (const BitString& x, const BitString& y) 
  534. {
  535.   BitString r; and(x, y, r); return r;
  536. }
  537.  
  538. inline BitString  operator | (const BitString& x, const BitString& y) 
  539. {
  540.   BitString r; or(x, y, r); return r;
  541. }
  542.  
  543. inline BitString  operator ^ (const BitString& x, const BitString& y) 
  544. {
  545.   BitString r; xor(x, y, r); return r;
  546. }
  547.  
  548. inline BitString  operator << (const BitString& x, int y) 
  549. {
  550.   BitString r; lshift(x, y, r); return r;
  551. }
  552.  
  553. inline BitString  operator >> (const BitString& x, int y) 
  554. {
  555.   BitString r; rshift(x, y, r); return r;
  556. }
  557.  
  558. inline BitString  operator - (const BitString& x, const BitString& y) 
  559. {
  560.   BitString r; diff(x, y, r); return r;
  561. }
  562.  
  563. inline BitString  operator + (const BitString& x, const BitString& y) 
  564. {
  565.   BitString r; cat(x, y, r); return r;
  566. }
  567.  
  568. inline BitString  operator + (const BitString& x, unsigned int y) 
  569. {
  570.   BitString r; cat(x, y, r); return r;
  571. }
  572.  
  573. inline BitString  operator ~ (const BitString& x) 
  574. {
  575.   BitString r; complement(x, r); return r;
  576. }
  577.  
  578. #endif
  579.  
  580. // status, matching
  581.  
  582. inline int BitString::length() const
  583.   return rep->len;
  584. }
  585.  
  586. inline int BitString::empty() const
  587.   return rep->len == 0;
  588. }
  589.  
  590. inline int BitString::index(const BitString& y, int startpos) const
  591. {   
  592.   return search(startpos, rep->len, y.rep->s, 0, y.rep->len);
  593. }
  594.  
  595. inline int BitString::index(const BitSubString& y, int startpos) const
  596. {   
  597.   return search(startpos, rep->len, y.S.rep->s, y.pos, y.pos+y.len);
  598. }
  599.  
  600. inline int BitString::contains(const BitString& y) const
  601. {   
  602.   return search(0, rep->len, y.rep->s, 0, y.rep->len) >= 0;
  603. }
  604.  
  605. inline int BitString::contains(const BitSubString& y) const
  606. {   
  607.   return search(0, rep->len, y.S.rep->s, y.pos, y.pos+y.len) >= 0;
  608. }
  609.  
  610. inline int BitString::contains(const BitString& y, int p) const
  611. {
  612.   return match(p, rep->len, 0, y.rep->s, 0, y.rep->len);
  613. }
  614.  
  615. inline int BitString::matches(const BitString& y, int p) const
  616. {
  617.   return match(p, rep->len, 1, y.rep->s, 0, y.rep->len);
  618. }
  619.  
  620. inline int BitString::contains(const BitSubString& y, int p) const
  621. {
  622.   return match(p, rep->len, 0, y.S.rep->s, y.pos, y.pos+y.len);
  623. }
  624.  
  625. inline int BitString::matches(const BitSubString& y, int p) const
  626. {
  627.   return match(p, rep->len, 1, y.S.rep->s, y.pos, y.pos+y.len);
  628. }
  629.  
  630. inline int BitString::contains(const BitPattern& r) const
  631. {
  632.   return r.search(rep->s, 0, rep->len) >= 0;
  633. }
  634.  
  635. inline int BitString::contains(const BitPattern& r, int p) const
  636. {
  637.   return r.match(rep->s, p, rep->len, 0);
  638. }
  639.  
  640. inline int BitString::matches(const BitPattern& r, int p) const
  641. {
  642.   return r.match(rep->s, p, rep->len, 1);
  643. }
  644.  
  645. inline int BitString::index(const BitPattern& r, int startpos) const
  646. {
  647.   return r.search(rep->s, startpos, rep->len);
  648. }
  649.  
  650. inline  int BitSubString::length() const
  651.   return len;
  652. }
  653.  
  654. inline  int BitSubString::empty() const
  655.   return len == 0;
  656. }
  657.  
  658. inline int operator != (const BitString& x, const BitString& y)
  659. {
  660.   return !(x == y);
  661. }
  662.  
  663. inline int operator>(const BitString& x, const BitString& y)
  664. {
  665.   return y < x;
  666. }
  667.  
  668. inline int operator>=(const BitString& x, const BitString& y)
  669. {
  670.   return y <= x;
  671. }
  672.  
  673. inline int BitString::first(unsigned int b) const
  674. {
  675.   return next(-1, b);
  676. }
  677.  
  678. inline int BitString::last(unsigned int b) const
  679. {
  680.   return previous(rep->len, b);
  681. }
  682.  
  683. inline int BitString::index(unsigned int bit, int startpos) const
  684. {
  685.   if (startpos >= 0)
  686.     return next(startpos - 1, bit);
  687.   else
  688.     return previous(rep->len + startpos + 1, bit);
  689. }
  690.  
  691. inline void BitString::right_trim(unsigned int b) 
  692. {
  693.   int nb = (b == 0)? 1 : 0;
  694.   rep = BStr_resize(rep, previous(rep->len, nb) + 1);
  695. }
  696.  
  697. inline void BitString::left_trim(unsigned int b)
  698. {
  699.   int nb = (b == 0)? 1 : 0;
  700.   int p = next(-1, nb);
  701.   rep = BStr_alloc(rep, rep->s, p, rep->len, rep->len - p);
  702. }
  703.  
  704. inline int BitString::test(int i) const
  705. {
  706.   return ((unsigned)(i) >= rep->len)? 0 : 
  707.          ((rep->s[BitStr_index(i)] & (1 << (BitStr_pos(i)))) != 0);
  708. }
  709.  
  710.  
  711. // subscripting
  712.  
  713. inline BitStrBit::BitStrBit(const BitStrBit& b) :src(b.src), pos(b.pos) {}
  714.  
  715. inline BitStrBit::BitStrBit(BitString& v, int p) :src(v), pos(p) {}
  716.  
  717. inline BitStrBit::~BitStrBit() {}
  718.  
  719. inline BitStrBit::operator unsigned int() const
  720. {
  721.   return src.test(pos);
  722. }
  723.  
  724. inline int BitStrBit::operator = (unsigned int b)
  725. {
  726.   src.assign(pos, b); return b;
  727. }
  728.  
  729. inline int BitStrBit::operator == (unsigned int b) const
  730. {
  731.   return src.test(pos) == b;
  732. }
  733.  
  734. inline int BitStrBit::operator != (unsigned int b) const
  735. {
  736.   return src.test(pos) != b;
  737. }
  738.  
  739. inline BitStrBit BitString::operator [] (int i)
  740. {
  741.   if ((unsigned)(i) >= rep->len) error("illegal bit index");
  742.   return BitStrBit(*this, i);
  743. }
  744.  
  745. inline BitSubString BitString::_substr(int first, int l)
  746. {
  747.   if (first < 0 || l <= 0 || (unsigned)(first + l) > rep->len)
  748.     return BitSubString(_nil_BitString, 0, 0) ;
  749.   else 
  750.     return BitSubString(*this, first, l);
  751. }
  752.  
  753. #endif
  754.